home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / prg_casm / snip9611.zip / BRESNHAM.C < prev    next >
C/C++ Source or Header  |  1996-11-24  |  3KB  |  132 lines

  1. /* +++Date last modified: 27-Oct-1996 */
  2.  
  3. /*
  4. ** Public Domain mode 13h Bresenham line/circle algorithms
  5. ** By Brian Dessent
  6. **
  7. ** Circle algorithm and other stuff rewritten by Kurt Kuzba
  8. **
  9. ** Written for Borland, modified for others by Bob Stout
  10. */
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <dos.h>
  15. #include <conio.h>
  16. #include "bresnham.h"
  17. #include "mk_fp.h"
  18.  
  19. /* uses BIOS to set video mode */
  20.  
  21. void setmode(int mode)
  22. {
  23.       union REGS r;
  24.  
  25.       r.x.ax = mode;
  26.       int86(0x10, &r, &r);
  27. }
  28.  
  29.  
  30. /* plots a dot at (x, y) with color c */
  31.  
  32. void plotdot(int x, int y, char c)
  33. {
  34.       register char far *addr;
  35.  
  36.       if(x < 0 || x > MAX_X || y < 0 || y > MAX_Y)
  37.             return;
  38.  
  39.       addr = MK_FP(0xa000, (SCREEN_WIDTH * y) + x);
  40.       *addr = c;
  41. }
  42.  
  43.  
  44. /* draws a line from (x, y) to (x2, y2) in color c */
  45.  
  46. void bresenham_line(int x, int y, int x2, int y2, char c)
  47. {
  48.       int i, steep = 0, sx, sy, dx, dy, e;
  49.  
  50.       dx = abs(x2 - x);
  51.       sx = ((x2 - x) > 0) ? 1 : -1;
  52.       dy = abs(y2 - y);
  53.       sy = ((y2 - y) > 0) ? 1 : -1;
  54.  
  55.       if(dy > dx)
  56.       {
  57.             steep =  x;   x =  y;   y = steep;  /* swap  x and  y */
  58.             steep = dx;  dx = dy;  dy = steep;  /* swap dx and dy */
  59.             steep = sx;  sx = sy;  sy = steep;  /* swap sx and sy */
  60.             steep = 1;
  61.       }
  62.  
  63.       e = 2 * dy - dx;
  64.       for(i = 0; i < dx; i++)
  65.       {
  66.             if(steep)
  67.                   plotdot(y, x, c);
  68.             else  plotdot(x, y, c);
  69.             while(e >= 0)
  70.             {
  71.                   y += sy;
  72.                   e -= 2 * dx;
  73.             }
  74.             x += sx;
  75.             e += 2 * dy;
  76.       }
  77.       plotdot(x2, y2, c);
  78. }
  79.  
  80. /* draws a circle at (xc, yc) with radius r in color c
  81. **
  82. ** note: the scaling factor of (SCREEN_WIDTH / SCREEN_HEIGHT) is used when
  83. ** updating d.  This makes round circles.  If you want ellipses, you can
  84. ** modify that ratio.
  85. */
  86.  
  87. void bresenham_circle(int xc, int yc, int r, char c)
  88. {
  89.       int x = 0, d = 2 * (1 - r), w = 2 * SCREEN_WIDTH / SCREEN_HEIGHT;
  90.  
  91.       while(r >= 0)
  92.       {
  93.             plotdot(xc + x, yc + r, c);
  94.             plotdot(xc + x, yc - r, c);
  95.             plotdot(xc - x, yc + r, c);
  96.             plotdot(xc - x, yc - r, c);
  97.             if (d + r > 0)
  98.                   d -= (w * --r) - 1;
  99.             if (x > d)
  100.                   d += (2 * ++x) + 1;
  101.       }
  102. }
  103.  
  104. #ifdef TEST
  105.  
  106. #ifndef __TURBOC__
  107.  #include "bc_rand.h"
  108. #endif
  109.  
  110. /* draws random lines and circles until a key is pressed in mode 13h */
  111. /* (draws in colors 0 - 63 only) */
  112.  
  113. int main()
  114. {
  115.       int i=0;
  116.  
  117.       randomize();
  118.       setmode(0x13);
  119.       while(!kbhit())
  120.       {
  121.             bresenham_line(random(SCREEN_WIDTH), random(SCREEN_HEIGHT),
  122.                   random(SCREEN_WIDTH), random(SCREEN_HEIGHT), i = ++i % 64);
  123.             bresenham_circle(random(SCREEN_WIDTH), random(SCREEN_HEIGHT),
  124.                   random(50), i = ++i % 64);
  125.       }
  126.       getch();
  127.       setmode(0x03);  /* set to color text mode, clearing screen */
  128.       return 0;
  129. }
  130.  
  131. #endif /* TEST */
  132.